package commands

import (
	"encoding/json"
	"fmt"
	"os"
	"text/tabwriter"

	"github.com/spf13/cobra"
	client "github.com/yourusername/lvm-manager/pkg/client"
)

// NetworkCommands returns a command object for network management
// It does NOT take a client; instead, each subcommand creates its own client using the --api flag.
func NetworkCommands() *cobra.Command {
	cmd := &cobra.Command{
		Use:     "network",
		Short:   "Manage networks",
		Aliases: []string{"net"},
	}

	cmd.AddCommand(
		networkListCmd(),
		networkGetCmd(),
		networkCreateCmd(),
		networkStartCmd(),
		networkStopCmd(),
		networkDeleteCmd(),
	)

	return cmd
}

// networkListCmd 列出所有网络
func networkListCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:     "list",
		Short:   "List all networks",
		Aliases: []string{"ls"},
		RunE: func(cmd *cobra.Command, args []string) error {
			apiClient := getAPIClient(cmd)
			networks, err := apiClient.ListNetworks()
			if err != nil {
				return fmt.Errorf("failed to list networks: %w", err)
			}

			// 表格输出
			w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
			fmt.Fprintln(w, "NAME\tUUID\tACTIVE\tPERSISTENT\tAUTOSTART\tBRIDGE\tFORWARD MODE")
			fmt.Fprintln(w, "----\t----\t------\t----------\t---------\t------\t------------")

			for _, n := range networks {
				active := "no"
				if n.Active {
					active = "yes"
				}
				persistent := "no"
				if n.Persistent {
					persistent = "yes"
				}
				autostart := "no"
				if n.Autostart {
					autostart = "yes"
				}

				fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
					n.Name, n.UUID, active, persistent, autostart, n.Bridge, n.ForwardMode)
			}
			w.Flush()

			fmt.Printf("\nTotal: %d networks\n", len(networks))
			return nil
		},
	}

	return cmd
}

// networkGetCmd 获取网络详情
func networkGetCmd() *cobra.Command {
	var outputJSON bool
	var includeXML bool

	cmd := &cobra.Command{
		Use:   "get <name>",
		Short: "Get network details",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			apiClient := getAPIClient(cmd)
			name := args[0]
			network, err := apiClient.GetNetwork(name, includeXML)
			if err != nil {
				return fmt.Errorf("failed to get network: %w", err)
			}

			if outputJSON {
				data, _ := json.MarshalIndent(network, "", "  ")
				fmt.Println(string(data))
			} else {
				fmt.Printf("Name:         %s\n", network.Name)
				fmt.Printf("UUID:         %s\n", network.UUID)
				fmt.Printf("Active:       %v\n", network.Active)
				fmt.Printf("Persistent:   %v\n", network.Persistent)
				fmt.Printf("Autostart:    %v\n", network.Autostart)
				fmt.Printf("Bridge:       %s\n", network.Bridge)
				fmt.Printf("Forward Mode: %s\n", network.ForwardMode)

				if includeXML && network.XMLConfig != "" {
					fmt.Printf("\nXML Configuration:\n%s\n", network.XMLConfig)
				}
			}
			return nil
		},
	}

	cmd.Flags().BoolVarP(&outputJSON, "json", "j", false, "Output in JSON format")
	cmd.Flags().BoolVarP(&includeXML, "xml", "x", false, "Include XML configuration")
	return cmd
}

// networkCreateCmd 创建网络
func networkCreateCmd() *cobra.Command {
	var spec client.CreateNetworkSpec

	cmd := &cobra.Command{
		Use:   "create",
		Short: "Create a new network",
		RunE: func(cmd *cobra.Command, args []string) error {
			apiClient := getAPIClient(cmd)
			if spec.Name == "" {
				return fmt.Errorf("name is required")
			}

			network, err := apiClient.CreateNetwork(&spec)
			if err != nil {
				return fmt.Errorf("failed to create network: %w", err)
			}

			fmt.Printf("Network '%s' created successfully (UUID: %s)\n", network.Name, network.UUID)
			fmt.Printf("Active: %v\n", network.Active)
			return nil
		},
	}

	cmd.Flags().StringVar(&spec.Name, "name", "", "Network name (required)")
	cmd.Flags().StringVar(&spec.ForwardMode, "forward-mode", "nat", "Forward mode (nat, route, bridge, none)")
	cmd.Flags().StringVar(&spec.Bridge, "bridge", "", "Bridge name")
	cmd.Flags().StringVar(&spec.IPAddress, "ip-address", "", "IP address (e.g. 192.168.100.1)")
	cmd.Flags().StringVar(&spec.NetMask, "netmask", "", "Netmask (e.g. 255.255.255.0)")
	cmd.Flags().StringVar(&spec.DHCPStart, "dhcp-start", "", "DHCP start address")
	cmd.Flags().StringVar(&spec.DHCPEnd, "dhcp-end", "", "DHCP end address")

	// 标记必需的标志
	cmd.MarkFlagRequired("name")

	return cmd
}

// networkStartCmd 启动网络
func networkStartCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "start <name>",
		Short: "Start a network",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			apiClient := getAPIClient(cmd)
			name := args[0]

			if err := apiClient.StartNetwork(name); err != nil {
				return fmt.Errorf("failed to start network: %w", err)
			}
			fmt.Printf("Network '%s' started\n", name)
			return nil
		},
	}
}

// networkStopCmd 停止网络
func networkStopCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "stop <name>",
		Short: "Stop a network",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			apiClient := getAPIClient(cmd)
			name := args[0]

			if err := apiClient.StopNetwork(name); err != nil {
				return fmt.Errorf("failed to stop network: %w", err)
			}
			fmt.Printf("Network '%s' stopped\n", name)
			return nil
		},
	}
}

// networkDeleteCmd 删除网络
func networkDeleteCmd() *cobra.Command {
	return &cobra.Command{
		Use:     "delete <name>",
		Short:   "Delete a network",
		Aliases: []string{"rm"},
		Args:    cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			apiClient := getAPIClient(cmd)
			name := args[0]

			if err := apiClient.DeleteNetwork(name); err != nil {
				return fmt.Errorf("failed to delete network: %w", err)
			}
			fmt.Printf("Network '%s' deleted\n", name)
			return nil
		},
	}
}
